//
//  CoreEditComponent.m
//  mobile
//
//  Created by abc on 2018/4/2.
//  Copyright © 2018年 azazie. All rights reserved.
//

#import "CoreEditComponent.h"

#import "TXFire.h"
#import <QMUIKit/QMUIKit.h>
#import <Masonry/Masonry.h>
#import <ReactiveObjC/ReactiveObjC.h>

@interface CoreEditComponent () <UITextFieldDelegate>
{
    CGFloat _leftPadding;
    CGFloat _rightPadding;
    
    UIColor *_borderColor;
    UIColor *_textFieldColor;
    UIColor *_textFieldTintColor;
    UIColor *_placeHolderLabelColor;
    
    UIColor *_disabledBGColor;
    UIColor *_disabledPlaceColor;
    
    UIFont *_defaultFont;
    UIFont *_defaultRaisedFont;
    
    NSInteger _maxLenght;
    
    BOOL _riseable;
    BOOL _rotateable;
}
@property (nonatomic, strong) BaseTextField *textField;
@property (nonatomic, strong) UILabel *placeHolder;
@property (nonatomic, strong) UIView *rightView;

@property (nonatomic, assign) BOOL placeholderRaised;

@property (nonatomic, strong) NSString *tmpInput;
@end

@implementation CoreEditComponent

#pragma mark - init method
+ (CoreEditComponent *)defaultEditComponent {
    return [[CoreEditComponent alloc] init];
}

- (instancetype)init {
    if (self = [super init]) {
        {
            _leftPadding = 10.f;
            _rightPadding = 20.f;
            
            _borderColor = UIColorRed;
            _textFieldTintColor = UIColorBlack;
            _textFieldColor = UIColorMakeWithHex(@"#333333");
            _placeHolderLabelColor = UIColorMakeWithHex(@"#888888");
            
            _defaultFont = UIFontMake(14.f);
            _defaultRaisedFont = UIFontMake(10.f);

            self.volatileRotateable(NO);
            self.placeHolderRiseable(YES);
            
            self.maxInputLenght(NSIntegerMax);
            
            self.bgColor(UIColorWhite);
        }
        self = self.configureSubviews.makeConstraints.subscribe;
        self.editable = YES;
    }
    return self;
}

- (instancetype)configureSubviews {
    [self addSubview:self.textField];
    [self addSubview:self.placeHolder];
    {
        self.disabledBackgroundColor(UIColorMakeWithHex(@"#FCFCFC"));
        self.disabledPlaceHolderColor(UIColorMakeWithHex(@"#C5C5C5"));
        
        self.textCleaarAble(NO);
    }
    return self;
}

- (instancetype)makeConstraints {
    [self.textField mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(self);
        make.left.equalTo(self).offset(_leftPadding);
        make.right.equalTo(self).offset(-_rightPadding);
        make.height.mas_equalTo(60.f-HEIGHT_OFFSET);
    }];

    [self.placeHolder mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.height.centerY.equalTo(self.textField);
        make.right.equalTo(self.textField).offset(-27);
    }];
    return self;
}

- (instancetype)subscribe {
    @weakify(self);
    [[self.tx_tapGestureRecognizer rac_gestureSignal] subscribeNext:^(__kindof UIGestureRecognizer * _Nullable x) {
        @strongify(self);
        [self viewTapResponse];
    }];
    
    [[self rac_signalForSelector:@selector(textFieldDidBeginEditing:) fromProtocol:@protocol(UITextFieldDelegate)] subscribeNext:^(RACTuple * _Nullable x) {
        @strongify(self);
        [self viewTapResponse];
    }];
    
    [[self.placeHolder.tx_tapGestureRecognizer rac_gestureSignal] subscribeNext:^(__kindof UIGestureRecognizer * _Nullable x) {
        @strongify(self);
        [self viewTapResponse];
    }];
    
    RACSignal *textChanged = [self.textField rac_signalForControlEvents:UIControlEventEditingChanged];
    RACSignal *textSet = [self.textField rac_signalForSelector:@selector(setText:)];
    
    self.contentChange = [RACSignal merge:@[textChanged, textSet]];
    [self.contentChange subscribeNext:^(id  _Nullable x) {
        @strongify(self);
        if (self.placeholderRaised != self.textField.text.length>0) {
            self.placeholderRaised = self.textField.text.length>0;
            [UIView animateWithDuration:0.08 animations:^{
                [self updatePlaceholderStyles];
            }];
        }
    }];

    [[RACObserve(self, invalid) skip:1] subscribeNext:^(id  _Nullable x) {
        @strongify(self);
        if (self.invalid && self.textField.isFirstResponder) {
            [self.textField resignFirstResponder];
        }

        [UIView animateWithDuration:0.08 animations:^{
            [self updateErrorStyles];
        }];
    }];

    [[RACObserve(self, editable) distinctUntilChanged] subscribeNext:^(id  _Nullable x) {
        @strongify(self);
        if (![x boolValue]) {
            self.tmpInput = self.textField.text;
        }
        self.textField.text = [x boolValue] ? self.tmpInput : @"";
        
        self.backgroundColor = ([x boolValue] ? [UIColor whiteColor] : self->_disabledBGColor);
        self.placeHolder.textColor = [x boolValue] ? self->_placeHolderLabelColor : self->_disabledPlaceColor;
        
        if ([x boolValue]) {
            self.placeHolder.hidden = self.textField.text.length > 0;
        } else {
            self.placeHolder.hidden = NO;
        }
    }];
    
    return self;
}

- (void)viewTapResponse {
    if (self.editable) {
        if (self.tapResponseBlock) {
            self.tapResponseBlock();
        } else {
            if (!self.textField.isFirstResponder) {
                [self.textField becomeFirstResponder];
            }
        }
    }
}

- (NSString *)currentText {
    return self.textField.text.length > 0 ? self.textField.text : nil;
}

#pragma mark - refresh edit component status

- (void)updateViewConstraints {
    [self.textField mas_updateConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self).offset(_leftPadding);
    }];
    if (self.rightView) {
        [self.rightView mas_updateConstraints:^(MASConstraintMaker *make) {
            make.right.equalTo(self).offset(-_rightPadding);
        }];
    } else {
        [self.textField mas_updateConstraints:^(MASConstraintMaker *make) {
            make.right.equalTo(self).offset(-_rightPadding);
        }];
    }
}

- (void)updatePlaceholderStyles {
    if (self.placeholderRaised) {
        if (_riseable) {
            self.placeHolder.transform = CGAffineTransformMakeTranslation(0, -7);
            self.placeHolder.font = _defaultRaisedFont;
            self.textField.contentVerticalAlignment = UIControlContentVerticalAlignmentBottom;
            [self.textField layoutSubviews];
        } else {
            self.placeHolder.hidden = YES;
        }
    } else {
        if (_riseable) {
            self.placeHolder.transform = CGAffineTransformIdentity;
            self.placeHolder.font = _defaultFont;
            self.textField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
            [self.textField layoutSubviews];
        } else {
            self.placeHolder.hidden = NO;
        }
    }
}

- (void)updateErrorStyles {
    if (self.isInvalid) {
        self.layer.borderWidth = 1;
        self.layer.borderColor = _borderColor.CGColor;
    } else {
        self.layer.borderWidth = 0;
        self.layer.borderColor = UIColorClear.CGColor;
    }
}

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    if (textField == self.textField && _maxLenght > 0) {
        if (string.length == 0) return YES;
        NSInteger existedLength = textField.text.length;
        NSInteger selectedLength = range.length;
        NSInteger replaceLength = string.length;
        if (existedLength - selectedLength + replaceLength > _maxLenght) {
            return NO;
        }
    }
    return YES;
}

#pragma mark - lazy load for subviews
- (BaseTextField *)textField {
    if (!_textField) {
        _textField = [[BaseTextField alloc] init];
        _textField.font = _defaultFont;
        _textField.textColor = _textFieldColor;
        _textField.delegate = self;
    }
    return _textField;
}

- (UILabel *)placeHolder {
    if (!_placeHolder) {
        _placeHolder = [[UILabel alloc] init];
        _placeHolder.font = _defaultFont;
        _placeHolder.textColor = _placeHolderLabelColor;
        _placeHolder.userInteractionEnabled = NO;
    }
    return _placeHolder;
}

#pragma mark - customization functions

/****  set colors  ****/
- (CoreEditComponent *(^)(UIColor *color))bgColor {
    return ^(UIColor *color) {
        self.backgroundColor = color;
        return self;
    };
}
- (CoreEditComponent *(^)(UIColor *color))textColor {
    return ^(UIColor *color) {
        _textFieldColor = color;
        self.textField.textColor = color;
        return self;
    };
}
- (CoreEditComponent *(^)(UIColor *color))textTintColor {
    return ^(UIColor *color) {
        _textFieldTintColor = color;
        self.textField.tintColor = color;
        return self;
    };
}
- (CoreEditComponent *(^)(UIColor *color))placeHolderColor {
    return ^(UIColor *color) {
        _placeHolderLabelColor = color;
        self.placeHolder.textColor = color;
        return self;
    };
}
- (CoreEditComponent *(^)(UIColor *color))errorBorderColor {
    return ^(UIColor *color) {
        _borderColor = color;
        if (!self.invalid) {
            self.layer.borderColor = _borderColor.CGColor;
        }
        return self;
    };
}
- (CoreEditComponent *(^)(UIColor *color))disabledBackgroundColor {
    return ^(UIColor *color) {
        _disabledBGColor = color;
        if (!self.editable) {
            self.backgroundColor = color;
        }
        return self;
    };
}
- (CoreEditComponent *(^)(UIColor *color))disabledPlaceHolderColor {
    return ^(UIColor *color) {
        _disabledPlaceColor = color;
        if (!self.editable) {
            self.placeHolder.textColor = color;
        }
        return self;
    };
}

/****  set texts & font  ****/
- (CoreEditComponent *(^)(UIFont *font))editFont {
    return ^(UIFont *font) {
        _defaultFont = font;
        self.textField.font = font;
        self.placeHolder.font = font;
        return self;
    };
}
- (CoreEditComponent *(^)(UIFont *font))risedFont {
    return ^(UIFont *font) {
        _defaultRaisedFont = font;
        if (self.placeholderRaised) {
            self.placeHolder.font = font;
        }
        return self;
    };
}
- (CoreEditComponent *(^)(NSString *text))text {
    return ^(NSString *text) {
        self.textField.text = text;
        return self;
    };
}
- (CoreEditComponent *(^)(NSString *text))placeHolderText {
    return ^(NSString *text) {
        self.placeHolder.text = text;
        return self;
    };
}

/****  configure rightview  ****/
- (CoreEditComponent *(^)(UIView *view))volatileView {
    return ^(UIView *view) {
        self.rightView = view;
        [self addSubview:self.rightView];
        [self.rightView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.centerY.equalTo(self);
            make.right.equalTo(self.mas_right).offset(-_rightPadding);
        }];
        [self.textField mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.centerY.equalTo(self);
            make.height.equalTo(self).offset(-HEIGHT_OFFSET);
            make.left.equalTo(self).offset(_leftPadding);
            make.right.equalTo(self.rightView.mas_left).offset(-_leftPadding);
        }];
        return self;
    };
}
- (CoreEditComponent *(^)(CGSize size))volatileSize {
    return ^(CGSize size) {
        [self.rightView mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.centerY.equalTo(self);
            make.right.equalTo(self.mas_right).offset(-_rightPadding);
            make.size.mas_equalTo(size);
        }];
        [self.textField mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.centerY.equalTo(self);
            make.height.equalTo(self).offset(-HEIGHT_OFFSET);
            make.left.equalTo(self).offset(_leftPadding);
            make.right.equalTo(self.rightView.mas_left).offset(-PADDING_FOR_CLEAR);
        }];
        return self;
    };
}
- (CoreEditComponent *(^)(BOOL rotateable))volatileRotateable {
    return ^(BOOL rotateable) {
        _rotateable = self.rightView && rotateable;
        return self;
    };
}
- (CoreEditComponent *(^)(void(^action)(void)))volatileAction {
    return ^(void(^action)(void)) {
        if (self.rightView && action) {
            [[self.rightView.tx_tapGestureRecognizer rac_gestureSignal] subscribeNext:^(__kindof UIGestureRecognizer * _Nullable x) {
                action();
            }];
        }
        return self;
    };
}

/****  change layout  ****/
- (CoreEditComponent *(^)(CGFloat distance))padding_left {
    return ^(CGFloat distance) {
        _leftPadding = distance;
        [self updateViewConstraints];
        return self;
    };
}
- (CoreEditComponent *(^)(CGFloat distance))padding_right {
    return ^(CGFloat distance) {
        _rightPadding = distance;
        [self updateViewConstraints];
        return self;
    };
}

/****  other prarmter  ****/
- (CoreEditComponent *(^)(NSInteger number))maxInputLenght {
    return ^(NSInteger number) {
        _maxLenght = number;
        return self;
    };
}
- (CoreEditComponent *(^)(BOOL riseable))placeHolderRiseable {
    return ^(BOOL riseable) {
        _riseable = riseable;
        return self;
    };
}
- (CoreEditComponent *(^)(BOOL clearable))textCleaarAble {
    return ^(BOOL clearable) {
        if (clearable) {
            self.textField.clearButtonMode = UITextFieldViewModeWhileEditing;
        } else {
            self.textField.clearButtonMode = UITextFieldViewModeNever;
        }
        return self;
    };
}
- (CoreEditComponent *(^)(BOOL isPassword))passwordInput{
    return ^(BOOL isPassword) {
        [self.textField setSecureTextEntry:isPassword];
        return self;
    };
}
- (CoreEditComponent *(^)(UIKeyboardType type))keyboardType {
    return ^(UIKeyboardType type) {
        self.textField.keyboardType = type;
        return self;
    };
}
- (CoreEditComponent *(^)(UIReturnKeyType type))returnkeyType {
    return ^(UIReturnKeyType type) {
        self.textField.returnKeyType = type;
        return self;
    };
}
- (CoreEditComponent *(^)(BOOL autoCapitalization))autoCapitalization {
    return ^(BOOL autoCapitalization) {
        if (autoCapitalization) {
            self.textField.autocapitalizationType = UITextAutocapitalizationTypeSentences;
        } else {
            self.textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
        }
        return self;
    };
}
- (CoreEditComponent *(^)(BOOL autoCorrection))autoCorrection {
    return ^(BOOL autoCorrection) {
        if (autoCorrection) {
            self.textField.autocorrectionType = UITextAutocorrectionTypeYes;
        } else {
            self.textField.autocorrectionType = UITextAutocorrectionTypeNo;
        }
        return self;
    };
}

- (CoreEditComponent *(^)(BOOL clearable))textFieldTouchAble {
    return ^(BOOL clearable) {
        self.textField.userInteractionEnabled = clearable;
        return self;
    };
}

@end
